package org.finesys.codegen.controller;

import java.util.List;

import org.finesys.codegen.dto.ColumnDTO;
import org.finesys.codegen.dto.GenTableGroupDTO;
import org.finesys.codegen.dto.TableDTO;
import org.finesys.codegen.entity.GenTable;
import org.finesys.codegen.entity.GenTableColumn;
import org.finesys.codegen.service.GenTableColumnService;
import org.finesys.codegen.service.GenTableService;
import org.finesys.common.core.constants.RestApiConfig;
import org.finesys.common.core.module.R;
import org.finesys.common.excel.annotaion.ResponseExcel;
import org.finesys.common.log.core.annotation.LogAnnotation;
import org.finesys.common.log.core.enums.OperateType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.lang.Assert;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/table")
@Tag(name = "表管理")
public class GenTableController {

    private final GenTableService genTableService;
    private final GenTableColumnService genTableColumnService;

    /**
     * 分页查询
     *
     * @param page     分页对象
     * @param genTable 表
     * @return
     */
    @GetMapping(RestApiConfig.PAGE)
    @Operation(summary = "分页查询", description = "分页查询")
    public R<?> page(Page<GenTable> page, GenTable genTable) {
        //默认数据源，赋值数据源id为空
        return R.success(genTableService.findPage(page, genTable));
    }

    @Operation(summary = "查询列表", description = "查询列表")
    @GetMapping(RestApiConfig.LIST)
    public R<?> list(GenTable genTable) {
        return R.success(genTableService.findList(genTable));
    }


    @PostMapping
    @Operation(summary = "新增", description = "新增")
    @LogAnnotation(title = "新增表", operateType = OperateType.INSERT)
    public R<?> add(@RequestBody GenTableGroupDTO genTableGroupDTO) {
        return R.judge(genTableService.saveTable(genTableGroupDTO));
    }

    @PutMapping
    @Operation(summary = "更新", description = "更新")
    @LogAnnotation(title = "修改表", operateType = OperateType.UPDATE)
    public R<?> update(@RequestBody GenTableGroupDTO genTableGroupDTO) {
        return R.judge(genTableService.updateTable(genTableGroupDTO));
    }

    @DeleteMapping
    @Operation(summary = "删除", description = "删除")
    @LogAnnotation(title = "删除表", operateType = OperateType.DELETE)
    public R<?> delete(@RequestBody Long[] ids) {
        return R.success(genTableService.removeTableByIds(ids));
    }

    @GetMapping("/{id}")
    @Operation(summary = "通过id查询", description = "通过id查询")
    public R<?> get(@PathVariable Long id) {
        return R.success(genTableService.getById(id));
    }

    @GetMapping(RestApiConfig.DETAILS)
    @Operation(summary = "通过条件查询", description = "通过条件查询")
    public R<?> details(GenTable genTable) {
        return R.success(genTableService.getOne(genTable));
    }

    @ResponseExcel
    @GetMapping(RestApiConfig.EXPORT_EXCEL)
    public List<GenTable> export(GenTable genTable) {
        return genTableService.findList(genTable);
    }

    @Operation(summary = "查询数据源下所有表", description = "查询数据源下所有表")
    @GetMapping(RestApiConfig.LIST + "/db")
    public R<?> queryDsTable(Page<TableDTO> page, TableDTO tableDTO) {
        return R.success(genTableService.queryDsTablePage(page, tableDTO));
    }


    /**
     * 获取表信息
     *
     * @param dsName    数据源
     * @param tableName 表名称
     */
    @GetMapping("/{dsName}/{tableName}")
    public R<GenTable> getTable(@PathVariable("dsName") String dsName, @PathVariable String tableName) {
        return R.success(genTableService.queryOrBuildTable(dsName, tableName));
    }

    /**
     * 查询数据源下表的全部字段
     *
     * @param columnDTO 查询表字段信息
     * @return page 分页对象
     */
    @GetMapping("/column/page")
    public R<?> getColumnPage(Page<ColumnDTO> page, ColumnDTO columnDTO) throws Exception {
        return R.success(genTableService.queryDsTableColumnPage(page, columnDTO));
    }


    /**
     * 查询数据源下表的全部字段
     *
     * @param dsName    数据源
     * @param tableName 表名称
     */
    @GetMapping("/column/{dsName}/{tableName}")
    public R<?> getColumn(@PathVariable("dsName") String dsName, @PathVariable String tableName) throws Exception {
        return R.success(genTableService.queryDsTableColumnList(dsName, tableName));
    }

    /**
     * 查询表DDL语句
     *
     * @param dsName    数据源
     * @param tableName 表名称
     */
    @GetMapping("/ddl/{dsName}/{tableName}")
    public R<?> getDdl(@PathVariable("dsName") String dsName, @PathVariable String tableName) throws Exception {
        return R.success(genTableService.queryTableDdl(dsName, tableName));
    }

    /**
     * 同步表信息
     *
     * @param dsName  数据源
     * @param tableId 表名称
     */
    @GetMapping("/sync/{dsName}/{tableId}")
    public R<GenTable> syncTable(@PathVariable("dsName") String dsName, @PathVariable Long tableId) {
        GenTable genTable = genTableService.getById(tableId);
        Assert.notNull(genTable, "不存在同步表信息");
        // 表配置删除
        genTableService.remove(
                Wrappers.<GenTable>lambdaQuery().eq(GenTable::getDsName, dsName).eq(GenTable::getTableId, tableId));
        // 字段配置删除
        genTableColumnService.remove(Wrappers.<GenTableColumn>lambdaQuery()
                .eq(GenTableColumn::getTableId, tableId));
        return R.success(genTableService.queryOrBuildTable(dsName, genTable.getTableName()));
    }


    /**
     * 修改表字段数据
     *
     * @param dsName         数据源
     * @param tableName      表名称
     * @param tableFieldList 字段列表
     */
    @PutMapping("/field/{dsName}/{tableName}")
    public R<String> updateTableField(@PathVariable("dsName") String dsName, @PathVariable String tableName,
                                      @RequestBody List<GenTableColumn> tableFieldList) {
        genTableColumnService.updateTableField(dsName, tableName, tableFieldList);
        return R.success();
    }
}
